package org.quickstep.application.util;

import java.awt.Component;

import javax.swing.Action;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JComponent;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JRadioButtonMenuItem;

import org.quickstep.application.action.CheckAction;
import org.quickstep.application.action.IActionGroup;
import org.quickstep.application.action.RadioAction;

public class MenuBuilder {
	
	public static final void build( JPopupMenu menu, Iterable<? extends Action> actions, boolean append ) {
		
		if ( menu == null || actions == null ) {
			throw new IllegalArgumentException();
		}
		
		if ( !append ) menu.removeAll();

		MenuBuilder builder = new MenuBuilder();
		for( Action a: actions ) {
			builder.addAction( menu, a );
		}
		builder.cleanup(menu);
	}

	public static final void build( JMenu menu, Iterable<? extends Action> actions, boolean append ) {
		build( menu.getPopupMenu(), actions, append );
	}
	

	public static final void buildMenuBar( JMenuBar menuBar, Iterable<? extends Action> actions, boolean append ) {

		if ( menuBar == null || actions == null ) {
			throw new IllegalArgumentException();
		}
		
		if ( !append ) menuBar.removeAll();

		for( Action a: actions ) {
			MenuBuilder builder = new MenuBuilder();
			builder.addAction( menuBar, a );
		}
	}
	
	private MenuBuilder() {}
	
	private int getItemCount( JComponent c ) {
		return c instanceof JMenu? ((JMenu)c).getMenuComponentCount(): c.getComponentCount();
	}
	
	private Component getItem( JComponent c, int i ) {
		return c instanceof JMenu? ((JMenu)c).getMenuComponent(i): c.getComponent(i);
	}
	
	private boolean isCheckAction( Action action ) {
		return action != null && action.getClass().getAnnotation( CheckAction.class ) != null;
	}

	
	private boolean isRadioAction( Action action ) {
		return action != null && action.getClass().getAnnotation( RadioAction.class ) != null;
	}
	
	
	private void addSeparator(JComponent menu) {
		
		if ( getItemCount(menu) > 0 /*&&  separators.get(menu) == null*/ ) {  
			menu.add( new JPopupMenu.Separator() );
//			System.out.println("MenuBuilder2.addSeparator() " + menu.getClass().getSimpleName());
//			separators.put(menu, Boolean.TRUE);
		}
		
		
		
	}
	
	private void addAction( JComponent menu, Action action ) {
		
		if ( action == null ) {
			addSeparator(menu);
		} else if ( action instanceof IActionGroup ) {
			addActionGroup( menu, (IActionGroup)action );
		} else {
		
			if ( isCheckAction(action)) {
				menu.add( new JCheckBoxMenuItem( action ));
			} else if ( isRadioAction(action)) {
				JRadioButtonMenuItem button = new JRadioButtonMenuItem( action );
//				getButtonGroup(menu).add( button );
				menu.add(button);
			} else {
				menu.add( new JMenuItem( action ) );
			}
		}
		
//		if ( action instanceof ICheckAction ) {
//			menu.add( new JCheckBoxMenuItem( action ));
//		} else if ( action instanceof IRadioAction ) {
//			JRadioButtonMenuItem button = new JRadioButtonMenuItem( action );
//			getButtonGroup(menu).add( button );
//			menu.add(button);
//		} else {
//			menu.add( new JMenuItem( action ) );
//		}
//		separators.put(menu, null);
	}
	
	private void addActionGroup(JComponent menu, IActionGroup actionGroup) {
		
		if ( actionGroup == null /*|| action.size() == 0*/ ) return;
		
		String name = (String) actionGroup.getValue( Action.NAME);
		
		if ( name != null && name.trim().length() > 0  ) {
			JMenu subMenu = new JMenu( actionGroup );
			menu.add( subMenu );
//			addSeparator(subMenu);
			for( Action a: actionGroup ) {
				addAction( subMenu, a );
			}
//			addSeparator(subMenu);
//			cleanup(subMenu);
		} else {
			addSeparator(menu);
			for( Action a: actionGroup ) {
				addAction( menu, a );
			}			
			addSeparator(menu);
		}
	}
	
//	private void build( JComponent menu, Action action ) {
//		
////		if ( action == null ) {
////			addSeparator(menu);
////		} else 
//		if ( action instanceof IActionGroup ) {
//			addActionGroup(menu, (IActionGroup)action);
//		} else {
//			addAction(menu, action);
//		}
//		
//	}

	private void cleanup(JComponent menu) {
		
		int itemCount = getItemCount(menu);
		if ( itemCount > 0 ) {
			Component c = getItem( menu, itemCount-1 );
			if ( c instanceof JPopupMenu.Separator ) {
				menu.remove( c );
//				separators.put(menu, null);
			}
		}
	}	
	
	
	
}
